//
//  WmcCalendarSelectView.swift
//  YPWatermarkCamera
//
//  Created by 赵新 on 2022/3/31.
//

import FSCalendar
import RxRelay
import UIKit
import YPBedrock

// MARK: - [WmcCalendarSelectView]

class WmcCalendarSelectView: UIView {
    // Lifecycle

    convenience init(minDate: Date, maxDate: Date) {
        self.init()
        self.minDate = minDate
        self.maxDate = maxDate
        self.makeUIX()
        self.bindViewActionX()
    }

    // Internal

    var photoStatistics: [WmcMediaTakePhotoDayModel] = []

    lazy var maskLayer: CAShapeLayer = {
        let maskLayer = CAShapeLayer()
        return maskLayer
    }()

    lazy var beforeBtn: WmcLeftImgRightTextBtn = {
        let btn = WmcLeftImgRightTextBtn(title: "上一月", image: "arrow_left".wmc_image)
        btn.setTintColor(.wmc_mainTheme)
        btn.font = 16.wmc_font
        btn.imgSize = 15.wmc_autoHor
        btn.imgTextSpacing = 0
        btn.yp.addEvent { [weak self] sender in
            guard let weakSelf = self else { return }
            let beforeDate = weakSelf.currentMonthDateRelay.value - 1.yp.month
            if beforeDate >= weakSelf.calendar.minimumDate {
                weakSelf.scrollDate(beforeDate)
            }
            weakSelf.calendar.currentPage = beforeDate
        }
        return btn
    }()

    lazy var titleView: WmcSelectTitleView = {
        let titleView = WmcSelectTitleView()
        return titleView
    }()

    lazy var nextBtn: WmcLeftTextRightImgBtn = {
        let btn = WmcLeftTextRightImgBtn(title: "下一月", image: "arrow_right".wmc_image)
        btn.setTintColor(.wmc_mainTheme)
        btn.font = 16.wmc_font
        btn.imgSize = 15.wmc_autoHor
        btn.imgTextSpacing = 0
        btn.yp.addEvent { [weak self] sender in
            guard let weakSelf = self else { return }
            let nextDate = weakSelf.currentMonthDateRelay.value + 1.yp.month
            if nextDate <= weakSelf.calendar.maximumDate {
                weakSelf.scrollDate(nextDate)
            }
            weakSelf.calendar.currentPage = nextDate
        }
        return btn
    }()

    lazy var monthLabel: UILabel = {
        let label = UILabel.YP.Create(
            font: 16.yp.uiFont(weight: .bold),
            color: UIColor.wmc_grayH2_323233,
            alignment: .center)
        return label
    }()

    /// 日历
    lazy var calendar: FSCalendar = {
        let y = 44.wmc_autoVer + 42
        let width = Wmc_screenWidth - 34
        let view = FSCalendar(frame: CGRect(x: 17, y: y, width: width, height: 315))
        view.locale = Locale(identifier: "zh_CN")
        view.headerHeight = 0
        view.calendarHeaderView.isHidden = false
        view.weekdayHeight = 20
        view.rowHeight = 86
        view.dataSource = self
        view.delegate = self
        view.placeholderType = .none
        view.allowsSelection = true
        view.allowsMultipleSelection = false
        view.calendarHeaderView.backgroundColor = .white
        view.calendarWeekdayView.backgroundColor = .white
        view.appearance.eventSelectionColor = .white
        view.appearance.selectionColor = .clear
        view.appearance.weekdayTextColor = .wmc_grayH2_323233
        view.register(WmcCalendarSeleceCell.self, forCellReuseIdentifier: "axc")
        view.appearance.todayColor = .clear
        view.appearance.todaySelectionColor = .clear
        view.appearance.titleTodayColor = .clear
        view.appearance.titleDefaultColor = .clear
        view.appearance.titlePlaceholderColor = .clear
        view.appearance.caseOptions = [.weekdayUsesSingleUpperCase, .headerUsesUpperCase]
        view.swipeToChooseGesture.isEnabled = true // Swipe-To-Choose
        view.backgroundColor = .white
        view.scrollEnabled = true

        addSubview(view)
        return view
    }()

    /// 展示的月份
    var currentMonthDateRelay: BehaviorRelay<Date> = .init(value: .init())

    var selectedDateClosure: ((Date) -> Void)?

    var minDate: Date = .init()

    var maxDate: Date = .init()

    /// 标题
    var title: String? {
        set { titleView.title = newValue }
        get { return titleView.title }
    }

    var selectedDate: Date? {
        didSet {
            calendar.reloadData()
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        let maskPath = UIBezierPath(
            roundedRect: bounds,
            byRoundingCorners: [.topLeft, .topRight],
            cornerRadii: 8.yp.cgSize)
        maskLayer.path = maskPath.cgPath
        layer.mask = maskLayer

        calendar.reloadData()
        calendar.layoutIfNeeded()
    }

    func makeUIX() {
        self.backgroundColor = .wmc_white_FFFFFF
        
        titleView.isShowLine = true
        titleView.leftBtn.setImage("close".wmc_image, for: .normal)
        title = "请选择日期"

        addSubview(titleView)
        addSubview(beforeBtn)
        addSubview(nextBtn)
        addSubview(monthLabel)
        addSubview(calendar)

        titleView.snp.makeConstraints { make in
            make.top.left.right.equalToSuperview()
            make.height.equalTo(44.wmc_autoVer)
        }

        beforeBtn.snp.makeConstraints { make in
            make.top.equalTo(titleView.snp.bottom)
            make.left.equalTo(Wmc_standardEdge.left)
            make.width.equalTo(70)
            make.height.equalTo(42)
        }

        nextBtn.snp.makeConstraints { make in
            make.top.width.height.equalTo(beforeBtn)
            make.right.equalTo(-Wmc_standardEdge.right)
        }

        monthLabel.snp.makeConstraints { make in
            make.top.height.equalTo(beforeBtn)
            make.left.equalTo(beforeBtn.snp.right)
            make.right.equalTo(nextBtn.snp.left)
        }

        // 监听
        currentMonthDateRelay.skip(1).subscribe(onNext: { [weak self] date in
            guard let weakSelf = self else { return }
            weakSelf.dateChangeSettingUI(date)
        }).disposed(by: rx.disposeBag)

        let date = WmcDateManager.shared.networkDate.value?.yp.string(.iso8601Day, identifier: .europe(.London)).yp.date(format: .iso8601Day, identifier: .asia(.Shanghai)) ?? Date()
        dateChangeSettingUI(date)
    }

    /// 设置滑动
    func scrollDate(_ date: Date) {
        calendar.setCurrentPage(date, animated: true)
        dateChangeSettingUI(date)
        currentMonthDateRelay.accept(date)
    }

    /// 设置UI
    func dateChangeSettingUI(_ date: Date) {
        // 设置标题
        let dateStr = date.yp.string(.ym_cn, identifier: .asia(.Shanghai))
        monthLabel.text = dateStr

        // 设置按钮隐藏
        let minimumDateStr = minDate.yp.string(.ym_cn, identifier: .asia(.Shanghai))
        let maximumDateStr = maxDate.yp.string(.ym_cn, identifier: .asia(.Shanghai))

        beforeBtn.isHidden = dateStr == minimumDateStr
        nextBtn.isHidden = dateStr == maximumDateStr
    }

    func bindViewActionX() {
        titleView.leftBtn.yp.addEvent { _ in
            YPApp.CurrentVC?.dismiss(animated: true)
        }
    }
}

// MARK: - FSCalendarDelegate

extension WmcCalendarSelectView: FSCalendarDelegate {
    // 日历滑动一月
    public func calendarCurrentPageDidChange(_ calendar: FSCalendar) {
        currentMonthDateRelay.accept(calendar.currentPage)
    }

    // 显示当前日历
    public func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
        return monthPosition == .current
    }

    // 显示当前日历
    public func calendar(_ calendar: FSCalendar, shouldDeselect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
        return monthPosition == .current
    }

    // 选中日期
    public func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
        var currentDate = Date()
        if let dateTemp = WmcDateManager.shared.networkDate.value {
            currentDate = dateTemp - 8.yp.hour

            if let dateTemp = currentDate.yp.string(.iso8601Day).yp.date(format: .iso8601Day) {
                currentDate = dateTemp
            }
        }

        var calendarDate = date
        if let dateTemp = date.yp.string(.iso8601Day).yp.date(format: .iso8601Day) {
            calendarDate = dateTemp
        }

        if calendarDate.timeIntervalSince1970 > currentDate.timeIntervalSince1970 {
            WmcHudManager.toast("无法搜索早于当前的日期")
            return
        }

        YPDevice.PlayShake(.light)
        selectedDateClosure?(calendarDate)
        YPApp.CurrentVC?.dismiss(animated: true)
    }

    // 取消选中日期
    func calendar(_ calendar: FSCalendar, didDeselect date: Date, at monthPosition: FSCalendarMonthPosition) {
//        switch selectType {
//        case .multi(max: _):
//            let newSelectedDates = calendar.selectedDates.map { $0 + 8.yp.hours }
//            self.selectBlock(newSelectedDates)
//        default: break
//        }
    }

    func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
//        print("bounds: \(bounds)")
    }
}

// MARK: - FSCalendarDataSource, FSCalendarDelegateAppearance

extension WmcCalendarSelectView: FSCalendarDataSource, FSCalendarDelegateAppearance {
    public func minimumDate(for calendar: FSCalendar) -> Date {
        return minDate
    }

    public func maximumDate(for calendar: FSCalendar) -> Date {
        return maxDate
    }

    public func calendar(_ calendar: FSCalendar, titleFor date: Date) -> String? {
        return nil
    }

    // cell
    public func calendar(_ calendar: FSCalendar, cellFor date: Date, at position: FSCalendarMonthPosition) -> FSCalendarCell {
        let _cell = calendar.dequeueReusableCell(withIdentifier: "axc", for: date, at: position)
        guard let cell = _cell as? WmcCalendarSeleceCell else { return _cell }

        var isContain = false
        for (_, item) in photoStatistics.enumerated() {
            if item.date == date.yp.string(.iso8601Day) {
                isContain = true
                break
            }
        }

        var isSelected: Bool = false
        if let selectedDate = selectedDate {
            if date.yp.string(.iso8601Day) == selectedDate.yp.string(.iso8601Day) {
                isSelected = true
            }
        }

        cell.update(date: date, position: position, isContainData: isContain, isSelected: isSelected)
        
        return cell
    }
}
